package at.hcmut.dev.mobile.barcamp;

import java.util.Date;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Messenger;


/**
 * Provides methods which is used to register location changed event.
 * 
 * @author IHNEL
 * 
 */
public abstract class LocationService {
	private static LocationManager locationManager;
	private static Activity context;
	private static LocationResult locationResult;
	private static LocationListener locationListener = new LocationListener() {

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}

		public void onProviderEnabled(String provider) {
		}

		public void onProviderDisabled(String provider) {
			// TODO LocationDisabledWarning
//			locationResult.OnFailed(context.getString(R.string.LocationDisabledWarning));
			locationResult.OnFailed("Location is disable");
		}

		public void onLocationChanged(Location location) {
			int i = 0;
			try{
			locationResult.OnAction(location);
			i = 1;
			CommonUtilities.locationRequestedTime = new Date();
			i = 2;
			} catch (Exception e) {
				e.printStackTrace();
//				Messenger.alert(context, "onLocationChanged "+  "error at line "+ i);
			}
		}
	};

	/**
	 * Request location.
	 * 
	 * @param context
	 * @param locationResult
	 *            : abstract class that contain callback method.
	 */
	public static void Register(final Activity context, final LocationResult locationResult) {
		int i = 0;
		try{
			
			LocationService.context = context;
			i = 1;
			LocationService.locationResult = locationResult;
			// initialize location manager.
			i = 2;
			locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
			i = 3;
			if(locationManager==null){
				i = 4;
				// TODO
//				locationResult.OnFailed(context.getString(R.string.error_LocationDisabled));
				i = 5;
				return;
			}
			i = 6;
			Criteria criteria = new Criteria();
			i = 7;
			String bestProvider = locationManager.getBestProvider(criteria, true);
			i = 8;

			if(bestProvider==null){
				i = 9;
				// TODO
//				locationResult.OnFailed(context.getString(R.string.error_LocationDisabled));
				i = 10;
				return;
			}
			i = 11;
			// Location location =
			// locationManager.getLastKnownLocation(bestProvider);
			Boolean locationOutOfDate = (new Date().getTime() - CommonUtilities.locationRequestedTime.getTime() > 300000);
			i = 12;
			if (CommonUtilities.location != null && !locationOutOfDate) {
				i = 13;
				System.out.print(CommonUtilities.location.toString());
				i = 14;
				locationResult.OnAction(CommonUtilities.location);// call the callback method.
				i = 15;
			} else {
				i = 16;
				locationManager.requestLocationUpdates(bestProvider, 20000, 1, locationListener);
				i = 17;
			}
		}catch(Exception ex){
			ex.printStackTrace();
			locationResult.OnFailed("Location Service"+ " error at line " + i);
		}
	}

	/**
	 * Stop listen for location changed event.
	 */
	public static void Dismiss() {
		locationManager.removeUpdates(locationListener);
		locationResult.OnFailed("");
	}

	private static String jsonToAddress(String jsonstring) {
		String address = "";
		try {
			JSONObject jo = new JSONObject(jsonstring);
			JSONArray ja = jo.getJSONArray("Placemark");

			JSONObject jsonAddress = ja.getJSONObject(0);
			String fullAdd = jsonAddress.getString("address");
			for (int i = 0; i < 3; i++) {
				address += fullAdd.substring(0, fullAdd.indexOf(","));
				if(i< 2	)
					address += ", ";
				fullAdd = fullAdd.substring(fullAdd.indexOf(",") + 1);
				
			}
			address  = address.trim();
			if(address.charAt(0) >= '0' && address.charAt(0)<='9')
				address = address.substring(address.indexOf(' '));
			if(address.charAt(address.length()-1) >='0' && address.charAt(address.length()-1) <= '9')
				address = address.substring(0,address.lastIndexOf(' '));
			
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return address.trim();
	}

	public static String getAddress(Context context, double longitude, double latitude) {

		try {
			HttpClient httpClient = new DefaultHttpClient();
			String url = String.format("http://maps.google.com/maps/geo?q=%s,%s", "" + latitude, "" + longitude);
			System.out.println(url);
			HttpGet httpGet = new HttpGet(url);
			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity entity = httpResponse.getEntity();
			String result = EntityUtils.toString(entity);
			System.out.println(result);
			return jsonToAddress(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
}
